"""
匿名请求闲鱼商品详情的工具
不需要登录，只需要获取 token 后请求商品信息
"""

import hashlib
import json
import time
from typing import Dict, Any, Optional
from urllib.parse import quote

import aiohttp
from loguru import logger


class AnonymousGoofishRequest:
    """匿名请求闲鱼API的工具类"""
    
    HOST_URL = "https://h5api.m.goofish.com/h5"
    APP_KEY = "34839810"
    
    def __init__(self):
        self.session: Optional[aiohttp.ClientSession] = None
        self.token: Optional[str] = None
    
    async def __aenter__(self):
        """异步上下文管理器入口"""
        self.session = aiohttp.ClientSession()
        return self
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """异步上下文管理器退出"""
        if self.session:
            await self.session.close()
    
    def get_timestamp(self) -> int:
        """获取时间戳（毫秒）"""
        return int(time.time() * 1000)
    
    def build_sign(self, token: str, timestamp: int, data: str) -> str:
        """
        构建签名
        
        Args:
            token: token值（可以为空字符串）
            timestamp: 时间戳（毫秒）
            data: JSON数据（字符串）
        
        Returns:
            MD5签名
        """
        sign_str = f"{token}&{timestamp}&{self.APP_KEY}&{data}"
        sign = hashlib.md5(sign_str.encode()).hexdigest()
        return sign
    
    async def get_token(self) -> Optional[str]:
        """
        步骤1：获取 token（通过推荐列表API）
        
        Returns:
            token 字符串，如果失败返回 None
        """
        try:
            # 构建请求参数
            request_data_dict = {
                "itemId": 991819717397,  # 使用目标商品ID
                "categoryId": "",
                "pageNum": 1,
                "pageSize": 30,
                "reqFrom": "xianyuweb"
            }
            request_data = json.dumps(request_data_dict, ensure_ascii=False)
            timestamp = self.get_timestamp()
            
            # 使用空 token 构建签名（首次请求）
            sign = self.build_sign("", timestamp, request_data)
            
            # 构建 URL
            api_name = "mtop.taobao.idle.item.web.recommend.list"
            url = f"{self.HOST_URL}/{api_name}/1.0/?"
            url_params = [
                "jsv=2.7.2",
                f"appKey={self.APP_KEY}",
                f"t={timestamp}",
                f"sign={sign}",
                "v=1.0",
                "type=originaljson",
                "accountSite=xianyu",
                "dataType=json",
                "timeout=20000",
                f"api={api_name}",
                "sessionOption=AutoLoginOnly",
                "spm_cnt=a21ybx.item.0.0"
            ]
            url += "&".join(url_params)
            
            # 构建请求头
            headers = {
                "accept": "application/json",
                "accept-language": "zh-HK,zh-CN;q=0.9,zh;q=0.8,zh-TW;q=0.7",
                "content-type": "application/x-www-form-urlencoded",
                "priority": "u=1, i",
                "sec-ch-ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": '"Windows"',
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-site",
                "referer": "https://www.goofish.com/"
            }
            
            # 发送请求（不设置 Cookie 头，让服务器自动返回）
            post_data = f"data={quote(request_data)}"
            async with self.session.post(url, data=post_data, headers=headers, timeout=10) as response:
                response_text = await response.text()
                result = json.loads(response_text)
                
                # 检查响应
                ret_codes = result.get("ret", [])
                
                # ⚠️ 注意：即使返回 FAIL_SYS_TOKEN_EMPTY，服务器也可能返回了 token cookie
                # 先尝试从 cookie_jar 中提取 token
                cookies = {}
                for cookie in self.session.cookie_jar:
                    cookies[cookie.key] = cookie.value
                
                # 获取 _m_h5_tk
                token_full = cookies.get("_m_h5_tk", "")
                if token_full:
                    token = token_full.split('_')[0] if '_' in token_full else token_full
                    self.token = token
                    logger.success(f"✅ Token获取成功: {token[:30]}...")
                    return token
                
                # 如果响应成功，但没获取到 token，可能是其他问题
                if ret_codes and any(code.startswith("SUCCESS") for code in ret_codes):
                    logger.warning("⚠️ 响应成功但未获取到token cookie")
                    return None
                else:
                    # 即使失败，也记录错误码，但可能 token 已经在 cookie 中了
                    logger.debug(f"Token请求返回: {ret_codes}, 但已检查cookie中的token")
                    return None
        except Exception as e:
            logger.exception(f"获取token时出错: {e}")
            return None
    
    async def get_item_detail(self, item_id: int) -> Optional[Dict[str, Any]]:
        """
        步骤2：获取商品详情
        
        Args:
            item_id: 商品ID
        
        Returns:
            商品详情数据，如果失败返回 None
        """
        try:
            # 如果还没有 token，先获取
            if not self.token:
                token = await self.get_token()
                if not token:
                    logger.error("❌ 无法获取token，无法请求商品详情")
                    return None
            
            # 构建请求参数
            request_data_dict = {
                "itemId": str(item_id)
            }
            request_data = json.dumps(request_data_dict, ensure_ascii=False)
            timestamp = self.get_timestamp()
            
            # 使用 token 构建签名
            sign = self.build_sign(self.token, timestamp, request_data)
            
            # 构建 URL
            api_name = "mtop.taobao.idle.pc.detail"
            url = f"{self.HOST_URL}/{api_name}/1.0/?"
            url_params = [
                "jsv=2.7.2",
                f"appKey={self.APP_KEY}",
                f"t={timestamp}",
                f"sign={sign}",
                "v=1.0",
                "type=originaljson",
                "accountSite=xianyu",
                "dataType=json",
                "timeout=20000",
                f"api={api_name}",
                "sessionOption=AutoLoginOnly",
                "spm_cnt=a21ybx.item.0.0"
            ]
            url += "&".join(url_params)
            
            # 构建请求头
            headers = {
                "accept": "application/json",
                "accept-language": "zh-HK,zh-CN;q=0.9,zh;q=0.8,zh-TW;q=0.7",
                "content-type": "application/x-www-form-urlencoded",
                "priority": "u=1, i",
                "sec-ch-ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": '"Windows"',
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-site",
                "referer": "https://www.goofish.com/"
            }
            
            # 构建 Cookie 头（包含之前获取的 token）
            cookie_parts = []
            for cookie in self.session.cookie_jar:
                cookie_parts.append(f"{cookie.key}={cookie.value}")
            if cookie_parts:
                headers["Cookie"] = "; ".join(cookie_parts)
            
            # 发送请求
            post_data = f"data={quote(request_data)}"
            async with self.session.post(url, data=post_data, headers=headers, timeout=10) as response:
                response_text = await response.text()
                result = json.loads(response_text)
                
                # 检查响应
                ret_codes = result.get("ret", [])
                if ret_codes and any(code.startswith("SUCCESS") for code in ret_codes):
                    logger.success(f"✅ 商品详情获取成功: itemId={item_id}")
                    return result.get("data", {})
                else:
                    logger.error(f"❌ 商品详情获取失败: {ret_codes}, msg={result.get('msg', 'N/A')}")
                    return None
        except Exception as e:
            logger.exception(f"获取商品详情时出错: {e}")
            return None


async def get_item_detail_anonymous(item_id: int) -> Optional[Dict[str, Any]]:
    """
    便捷函数：匿名获取闲鱼商品详情
    
    Args:
        item_id: 商品ID（例如：991819717397）
    
    Returns:
        商品详情数据，如果失败返回 None
    
    Example:
        ```python
        import asyncio
        from agent.utils.anonymous_request import get_item_detail_anonymous
        
        async def main():
            detail = await get_item_detail_anonymous(991819717397)
            if detail:
                print(f"商品标题: {detail.get('itemDO', {}).get('title', 'N/A')}")
        
        asyncio.run(main())
        ```
    """
    async with AnonymousGoofishRequest() as client:
        return await client.get_item_detail(item_id)


if __name__ == "__main__":
    """测试脚本"""
    import asyncio
    
    async def test():
        item_id = 991819717397
        print(f"正在获取商品详情: {item_id}")
        
        detail = await get_item_detail_anonymous(item_id)
        if detail:
            item_do = detail.get("itemDO", {})
            seller_do = detail.get("sellerDO", {})
            
            print("\n" + "="*60)
            print("商品信息:")
            print(f"  标题: {item_do.get('title', 'N/A')}")
            print(f"  价格: ¥{item_do.get('soldPrice', item_do.get('price', 'N/A'))}")
            print(f"  商品ID: {item_do.get('itemId', 'N/A')}")
            print(f"\n卖家信息:")
            print(f"  卖家昵称: {seller_do.get('nick', 'N/A')}")
            print(f"  卖家ID: {seller_do.get('sellerId', 'N/A')}")
            print(f"  头像: {seller_do.get('portraitUrl', 'N/A')}")
            print("="*60)
        else:
            print("获取失败")
    
    try:
        asyncio.run(test())
    except UnicodeEncodeError:
        # Windows 控制台编码问题，使用 logger 输出
        logger.info("测试完成（控制台编码问题已忽略）")

